package com.gupaoedu.vip.pattern.springmvc2.beans.support;

import com.gupaoedu.vip.pattern.springmvc2.beans.config.MyBeandefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class MyBeanDefinitionReader {

    //配置文件的config对象
    private Properties config = new Properties();

    //默认扫描的key
    private final String SCAN_PACKAGE = "scanPackage";

    //存放扫描到的所有class的名字
    private List<String> registryBeanClasses = new ArrayList<String>();

    public MyBeanDefinitionReader(String... locations){
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(locations[0].replace("classpath:",""));
        try {
            config.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null != is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        doScanner(config.getProperty(SCAN_PACKAGE));
    }

    private void doScanner(String scanPackage) {
        URL url = this.getClass().getClassLoader().getResource("/"+scanPackage.replaceAll("\\.","/"));
        File classpath = new File(url.getFile());
        for (File file:classpath.listFiles() ) {
            if(file.isDirectory()){
                doScanner(scanPackage+"."+file.getName());
            }else{
                if(!file.getName().endsWith(".class")){continue;}
                String className = (scanPackage+"."+file.getName().replace(".class",""));
                registryBeanClasses.add(className);
            }
        }
    }
    public Properties getConfig(){
        return this.config;
    }

    //配置文件中扫描到的配置信息转换成BeanDefinition ,便于IOC容器注册
    public List<MyBeandefinition> loadBeanDefinitions(){
        List<MyBeandefinition> result = new ArrayList<MyBeandefinition>();
        try {
            for (String beanClassName:registryBeanClasses) {
                Class<?> clazz = Class.forName(beanClassName);
                if(clazz.isInterface()){continue;}
                //beanName 有三种情况
                // 1 默认的是类名首字母小写
                // 2 自定义名字
                // 3 接口注入
                result.add(doCreate(toLowerFirstCase(clazz.getSimpleName()),clazz.getName()));
//                result.add(doCreate(clazz.getName(),clazz.getName()));
                Class<?> [] interfaces = clazz.getInterfaces();
                for (Class<?> i:interfaces) {
                    //如果有多个实现类
                    result.add(doCreate(i.getName(), clazz.getName()));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    //把配置信息解析成beanDefinition
    public MyBeandefinition doCreate(String factoryBeanName, String beanName){
        MyBeandefinition beandefinition = new MyBeandefinition();
        beandefinition.setBeanClassName(beanName);
        beandefinition.setFactoryBeanName(factoryBeanName);
        return beandefinition;
    }

    private String toLowerFirstCase(String simpleName) {
        char [] chars = simpleName.toCharArray();
        //之所以加，是因为大小写字母的ASCII码相差32，
        // 而且大写字母的ASCII码要小于小写字母的ASCII码
        //在Java中，对char做算学运算，实际上就是对ASCII码做算学运算
        chars[0] += 32;
        return String.valueOf(chars);
    }
}
